#pragma once

#include <windows.h>

#define MSGSIZE	512			// Default the size of a message

#define	MSG_REGISTER			1
#define MSG_REGISTERRESULT		2
#define MSG_START				3
#define MSG_QUESTION			4
#define MSG_CHOICE				5
#define MSG_ANSWERANDMARK		6
#define MSG_QUIT				7
#define MSG_UPDATELIST			8
#define MSG_FINALMARK			9

//////////////////////MESSAGE STRUCTURE///////////////////////////

// A generic message
typedef struct {
	BYTE opcode;
	BYTE record[MSGSIZE - sizeof(BYTE)];
} MESSAGE, *PMESSAGE;

// Client send this message to server for register
typedef struct {
	BYTE opcode;
	char nickname[20];
	BYTE zero[MSGSIZE - sizeof(BYTE) - 20];
} M_REGISTER, *PM_REGISTER;

char* MRegister_GetNickname(PM_REGISTER p);

// Server send this message to result the client's register
typedef struct {
	BYTE opcode;
	bool issuccess;
	BYTE nMember;
	BYTE zero[MSGSIZE - 2 * sizeof(BYTE) - sizeof(bool)];
} M_REGISTERRESULT, *PM_REGISTERRESULT;

bool MRegisterResult_IsSuccess(PM_REGISTERRESULT p);
BYTE MRegisterResult_GetNMember(PM_REGISTERRESULT p);

// Server send this message to notify that have a new member
typedef struct {
	BYTE opcode;
	char nickname[20];
	BYTE zero[MSGSIZE - sizeof(BYTE) - 20];
} M_NEWMEM, *PM_NEWMEM;

char* MNewMem_GetNickname(PM_NEWMEM p);

// Server send this message to notify the game start
typedef struct {
	BYTE opcode;
	BYTE mark;
	BYTE zero[MSGSIZE - 2 * sizeof(BYTE)];
} M_START, *PM_START;

BYTE MStart_GetMark(PM_START p);

// Server send this message to give a question and its choices
typedef struct {
	BYTE opcode;
	wchar_t question[125];
	wchar_t choice1[30], choice2[30], choice3[30], choice4[30];
	BYTE zero[MSGSIZE - sizeof(BYTE) - 2 * (125 + 30 * 4) - 2];		// 2 pad bytes
} M_QUESTION, *PM_QUESTION;

wchar_t* MQuestion_GetQuestion(PM_QUESTION p);
wchar_t* MQuestion_GetChoice1(PM_QUESTION p);
wchar_t* MQuestion_GetChoice2(PM_QUESTION p);
wchar_t* MQuestion_GetChoice3(PM_QUESTION p);
wchar_t* MQuestion_GetChoice4(PM_QUESTION p);

// Client send this message to give its choice
typedef struct {
	BYTE opcode;
	BYTE choice;
	BYTE zero[MSGSIZE - 2 * sizeof(BYTE)];
} M_CHOICE, *PM_CHOICE;

BYTE MChoie_GetChoice(PM_CHOICE p);

// Server send this message to notify the answer and the client's mark
typedef struct {
	BYTE opcode;
	BYTE answer, mark;
	BYTE zero[MSGSIZE - 3 * sizeof(BYTE)];
} M_ANSWERANDMARK, *PM_ANSWERANDMARK;

BYTE MAnswerAndMark_GetAnswer(PM_ANSWERANDMARK p);
BYTE MAnswerAndMark_GetMark(PM_ANSWERANDMARK p);

// Server send this message to notify the client is wrong over 3 quesstions
// After client quit the game
typedef struct {
	BYTE opcode;
	BYTE zero[MSGSIZE - sizeof(BYTE)];
} M_QUIT, *PM_QUIT;

// Server send this message to update the current member list
typedef struct {
	BYTE opcode;
	char quitnickname[20];
	BYTE quitList[MSGSIZE - sizeof(BYTE) - 20];
} M_UPDATELIST, *PM_UPDATELIST;

char* MUpdateList_GetQuitNickname(PM_UPDATELIST p);

// Server send this message to notify client's final mark and the winner
typedef struct {
	BYTE opcode;
	BYTE finalmark;
	char nicknamewinner[20];
	BYTE zero[MSGSIZE - 2 * sizeof(BYTE) - 20];
} M_FINALMARK, *PM_FINALMARK;

BYTE MFinalMark_GetMark(PM_FINALMARK p);
char* MFinalMark_GetNicknameWinner(PM_FINALMARK p);